package cn.istartfinancial.controller.flowable;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import lombok.extern.slf4j.Slf4j;
import org.apache.batik.transcoder.TranscoderInput;
import org.apache.batik.transcoder.TranscoderOutput;
import org.apache.batik.transcoder.image.PNGTranscoder;
import org.apache.commons.lang3.StringUtils;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.editor.constants.ModelDataJsonConstants;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Model;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.Map;
import static org.flowable.editor.constants.ModelDataJsonConstants.MODEL_ID;
import static org.flowable.editor.constants.ModelDataJsonConstants.MODEL_NAME;

/**
 * @author: Nzp
 * @date: 2018/8/24
 * @description: 模型相关
 */
@Slf4j
@RestController
@RequestMapping("service")
public class ModelController
{

    @Autowired private ObjectMapper objectMapper;
    @Autowired private RepositoryService repositoryService;

    @RequestMapping(value = "/model/{modelId}/json", method = RequestMethod.GET, produces = "application/json")
    public ObjectNode getEditorJson(@PathVariable String modelId)
    {
        ObjectNode modelNode = null;
        Model model = repositoryService.getModel(modelId);
        if (model != null)
        {
            try
            {
                if (StringUtils.isNotEmpty(model.getMetaInfo()))
                {
                    modelNode = (ObjectNode) objectMapper.readTree(model.getMetaInfo());
                } else
                {
                    modelNode = objectMapper.createObjectNode();
                    modelNode.put(MODEL_NAME, model.getName());
                }
                modelNode.put(MODEL_ID, model.getId());
                ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(
                        new String(repositoryService.getModelEditorSource(model.getId()), "utf-8"));
                modelNode.set("model", editorJsonNode);

            } catch (Exception e)
            {
                log.error("Error creating model JSON", e);
                throw new FlowableException("Error creating model JSON", e);
            }
        }
        return modelNode;
    }

    private ObjectNode getJsonNodes(String modelId)
    {
        int revision = 1;
        String key = "processKey";

        ObjectNode modelNode = objectMapper.createObjectNode();
        modelNode.put("modelId", modelId);
        modelNode.put("revision", revision);
        // 名称 描述
        // modelNode.put("name", name);
        // modelNode.put("description", description);

        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace",
                "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        modelNode.set("model", editorNode);
        return modelNode;
    }

    @PostMapping(value = "/model/{modelId}/save")
    @ResponseStatus(value = HttpStatus.OK)
    public void saveModel(@PathVariable String modelId,
                          HttpServletRequest request, HttpServletResponse response)
    {
        try
        {
            Map<String, String[]> map = request.getParameterMap();
            JSONObject jsonObject = new JSONObject();
            for (Map.Entry<String, String[]> entry : map.entrySet())
            {
                String data = entry.getKey() + "=" + (entry.getValue()[0]);
                jsonObject = JSON.parseObject(data);
            }
            String name = (String) jsonObject.get("name");
            String description = (String) jsonObject.get("description");
            String json_xml = (String) jsonObject.get("json_xml");
            String svg_xml = (String) jsonObject.get("svg_xml");

            JSONObject object = new JSONObject();
            object.put(ModelDataJsonConstants.MODEL_NAME, name);
            object.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
            Model model = repositoryService.getModel(modelId);
            model.setMetaInfo(object.toString());
            model.setName(name);
            repositoryService.saveModel(model);
            repositoryService.addModelEditorSource(model.getId(), json_xml.getBytes("utf-8"));

            InputStream svgStream = new ByteArrayInputStream(svg_xml.getBytes("utf-8"));
            TranscoderInput input = new TranscoderInput(svgStream);
            PNGTranscoder transcoder = new PNGTranscoder();
            // Setup output
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            TranscoderOutput output = new TranscoderOutput(outStream);
            // Do the transformation
            transcoder.transcode(input, output);
            final byte[] result = outStream.toByteArray();
            repositoryService.addModelEditorSourceExtra(model.getId(), result);
            outStream.close();
        } catch (Exception e)
        {
            log.error("Error saving model", e);
            throw new FlowableException("Error saving model", e);
        }
    }
}